﻿using Microsoft.VisualStudio.TextTemplating;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace CodeGenerator
{
    public partial class MainFrom : Form
    {
        //定义引擎对象
        private Engine engine; //Microsoft.VisualStudio.TextTemplating命名空间下
        string connString = null;
        Dictionary<string, DbTable> dicTable = new Dictionary<string, DbTable>();
        Dictionary<string, string> dicOutputEntity = new Dictionary<string, string>();
        Dictionary<string, string> dicOutputInterface = new Dictionary<string, string>();
        Dictionary<string, string> dicOutputImp = new Dictionary<string, string>();
        Dictionary<string, string> dicOutputApp = new Dictionary<string, string>();
        public MainFrom()
        {
            InitializeComponent();
            dgv_tables.AutoGenerateColumns = false;
            this.engine = new Engine();
            txtServer.Text = ConfigurationManager.AppSettings["server"] + "";
            txtDB.Text = ConfigurationManager.AppSettings["database"] + "";
            txtUser.Text = ConfigurationManager.AppSettings["username"] + "";
            txtPwd.Text = ConfigurationManager.AppSettings["password"] + "";
        }


        private void btnGenerate_Click(object sender, EventArgs e)
        {
            BuildCode();
            ShowCode(txtModel, dicOutputEntity);
            ShowCode(txtInterface, dicOutputInterface);
            ShowCode(txtImp, dicOutputImp);
            ShowCode(txtApp, dicOutputApp);
        }

        private void BuildCode()
        {
            dicOutputEntity.Clear();
            dicOutputInterface.Clear();
            dicOutputImp.Clear();
            dicOutputApp.Clear();
            //创建参数对象
            HostParam param = new HostParam();
            param.NameSpace = this.txtNameSpace.Text;
            //生成代码
            dicOutputEntity = GenerateCode(param, "Entity", isentity: true);
            dicOutputInterface = GenerateCode(param, "Interface");
            dicOutputImp = GenerateCode(param, "Imp");
            dicOutputApp = GenerateCode(param, "App");
        }

        private void ShowCode(RichTextBox txt, Dictionary<string, string> dic)
        {
            foreach (KeyValuePair<string, string> kv in dic)
            {
                txt.Text += kv.Value + "\r\n";
            }
        }
        private string  OutFileName(string tablename,string type)
        {
            HostParam param = new HostParam();
            param.Type = type;
            param.TableName = tablename;
            //模板文件
            string templateFile = ConfigurationManager.AppSettings["outFileName"] + "";
            string content = File.ReadAllText(templateFile);
            //创建宿主
            TemplateHost host = new TemplateHost
            {
                TemplateFile = templateFile,
                Param = param
            };
           
            return engine.ProcessTemplate(content, host);
        }
        private Dictionary<string, string> GenerateCode(HostParam param, string type, bool isentity = false)
        {
            Dictionary<string, string> tempDic = new Dictionary<string, string>();
            //模板文件
            string templateFile = ConfigurationManager.AppSettings[type];
            string content = File.ReadAllText(templateFile);

            //创建宿主
            TemplateHost host = new TemplateHost
            {
                TemplateFile = templateFile,
                Param = param
            };

            //生成代码
            foreach (KeyValuePair<string, DbTable> item in dicTable)
            {
                param.TableName = item.Key;
                string outfilename = OutFileName(item.Key, type).Replace("\r\n","");
                if (isentity)
                {
                    param.ColumnList = DBHelper.GetSchema(connString, param.TableName, checkView.Checked);
                }
                tempDic.Add(outfilename, engine.ProcessTemplate(content, host));
            }
            return tempDic;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            WirteCodeFile(dicOutputEntity, "Entity");
            WirteCodeFile(dicOutputInterface, "Interface");
            WirteCodeFile(dicOutputImp, "Imp");
            WirteCodeFile(dicOutputApp, "App");
            Process.Start("Explorer.exe", txtPath.Text);

        }
        private void WirteCodeFile(Dictionary<string, string> dic, string type)
        {
            string filePath = string.Format("{0}\\{1}", txtPath.Text, type);
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            foreach (KeyValuePair<string, string> item in dic)
            {
                File.WriteAllText(filePath + "\\" + item.Key + ".cs", item.Value);
            }
        }

        private void dgv_tables_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            DataGridView grid = (DataGridView)sender;
            Rectangle rectangle = new Rectangle(e.RowBounds.Location.X,
                e.RowBounds.Location.Y,
                grid.RowHeadersWidth - 4,
                e.RowBounds.Height);

            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
                grid.RowHeadersDefaultCellStyle.Font,
                rectangle,
                grid.RowHeadersDefaultCellStyle.ForeColor,
                TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            connString = string.Format("Data Source={0};Database={1};uid={2};pwd={3}", txtServer.Text, txtDB.Text, txtUser.Text, txtPwd.Text);
            dgv_tables.DataSource = DBHelper.GetTables(connString, txtDB.Text, txtqueryTableName.Text, checkView.Checked);
            if (checkConnect.Checked) { SvaeConfig(); }
        }

        private void SvaeConfig()
        {
            Dictionary<string, string> dicConfig = new Dictionary<string, string>();
            dicConfig.Add("server", txtServer.Text);
            dicConfig.Add("database", txtDB.Text);
            dicConfig.Add("username", txtUser.Text);
            dicConfig.Add("password", txtPwd.Text);
            EditConfig(dicConfig);
        }

        private void EditConfig(Dictionary<string, string> dic)
        {
            Configuration cfa = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            foreach (KeyValuePair<string, string> kv in dic)
            {
                cfa.AppSettings.Settings.Remove(kv.Key);
                cfa.AppSettings.Settings.Add(kv.Key, kv.Value);
            }
            cfa.Save();
        }

        private void checkAll_CheckedChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < dgv_tables.RowCount; i++)
            {
                if (checkAll.Checked)
                {
                    dgv_tables.Rows[i].Cells["select"].Value = 1;
                    string tablename = dgv_tables.Rows[i].Cells["TableName"].Value + "";
                    dicTable.Add(tablename, new DbTable { TableName = tablename });
                }
                else
                {
                    dgv_tables.Rows[i].Cells["select"].Value = 0;
                    string tablename = dgv_tables.Rows[i].Cells["TableName"].Value + "";
                    dicTable.Remove(tablename);
                }
            }
            txtTableName.Text = string.Join(",", dicTable.Keys);
        }

        private void dgv_tables_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView grid = (DataGridView)sender;
            string tablename = dgv_tables.Rows[e.RowIndex].Cells["TableName"].Value + "";
            if (grid.Columns[e.ColumnIndex].Name == "select")
            {
                if (Convert.ToBoolean(grid.Rows[e.RowIndex].Cells[e.ColumnIndex].EditedFormattedValue))
                {

                    dicTable.Add(tablename, new DbTable { TableName = tablename });
                }
                else
                {
                    dicTable.Remove(tablename);
                }
            }
            txtTableName.Text = string.Join(",", dicTable.Keys);
        }

        private void btnSelectFoler_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            if (fbd.ShowDialog() == DialogResult.OK)
            {
                txtPath.Text = fbd.SelectedPath + "\\";
            }
        }

        private void btnQueryTable_Click(object sender, EventArgs e)
        {
            dgv_tables.DataSource = DBHelper.GetTables(connString, txtDB.Text, txtqueryTableName.Text, checkView.Checked);
        }
    }
}
